From 5d0cb3f2e93e783248b1aa914a278e4ae0c86844 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 14 Jan 2015 00:19:27 -0800 Subject: [PATCH] Overhaul how Config is passed around This commit started out by moving the hash map of configuration values into `Config` and then removing all calls to config::all_configs in favor of taking a `&Config` argument. This initial step was taken to prevent reloading configuration many times from disk, but it also provides a nice house for configuration to be loaded from. The commit snowballed into purging `MultiShell` as an argument all over the place and passing around `Config` instead. Along the way a few other breaking changes were made: * The `config_for_key` and `config_list` subcommands have been removed. These commands are not ready to be stabilized and need some more work. In general the `cargo config` system needs to be cleaned out and built back up with a new interface, at which point these subcommands can return. * The old and deprecated behavior of `cargo update foo` has been removed. --- src/bin/bench.rs | 13 ++-- src/bin/build.rs | 13 ++-- src/bin/cargo.rs | 26 ++++---- src/bin/clean.rs | 13 ++-- src/bin/config_for_key.rs | 43 ------------- src/bin/config_list.rs | 41 ------------- src/bin/doc.rs | 9 ++- src/bin/fetch.rs | 9 ++- src/bin/generate_lockfile.rs | 9 ++- src/bin/git_checkout.rs | 10 +-- src/bin/help.rs | 5 +- src/bin/locate_project.rs | 5 +- src/bin/login.rs | 13 ++-- src/bin/new.rs | 9 ++- src/bin/owner.rs | 9 ++- src/bin/package.rs | 9 ++- src/bin/pkgid.rs | 9 ++- src/bin/publish.rs | 9 ++- src/bin/read_manifest.rs | 8 +-- src/bin/run.rs | 13 ++-- src/bin/search.rs | 9 ++- src/bin/test.rs | 13 ++-- src/bin/update.rs | 24 +++----- src/bin/verify_project.rs | 8 +-- src/bin/version.rs | 5 +- src/bin/yank.rs | 9 ++- src/cargo/core/package_id_spec.rs | 4 +- src/cargo/core/registry.rs | 10 +-- src/cargo/core/source.rs | 6 +- src/cargo/lib.rs | 40 +++++------- src/cargo/ops/cargo_clean.rs | 16 ++--- src/cargo/ops/cargo_compile.rs | 63 +++++++++++-------- src/cargo/ops/cargo_doc.rs | 11 ++-- src/cargo/ops/cargo_fetch.rs | 10 ++- src/cargo/ops/cargo_generate_lockfile.rs | 23 ++++--- src/cargo/ops/cargo_new.rs | 23 +++---- src/cargo/ops/cargo_package.rs | 35 ++++++----- src/cargo/ops/cargo_pkgid.rs | 9 +-- src/cargo/ops/cargo_read_manifest.rs | 28 +++++---- src/cargo/ops/cargo_run.rs | 7 ++- src/cargo/ops/cargo_rustc/context.rs | 49 ++++++++------- src/cargo/ops/cargo_rustc/custom_build.rs | 2 +- src/cargo/ops/cargo_rustc/job_queue.rs | 6 +- src/cargo/ops/cargo_rustc/mod.rs | 41 +++++++------ src/cargo/ops/cargo_test.rs | 22 ++++--- src/cargo/ops/registry.rs | 75 ++++++++++++----------- src/cargo/sources/git/source.rs | 5 +- src/cargo/sources/path.rs | 29 +++++---- src/cargo/sources/registry.rs | 10 +-- src/cargo/util/config.rs | 67 ++++++++++---------- src/cargo/util/toml.rs | 20 +++--- tests/test_cargo.rs | 13 ++-- tests/test_cargo_compile_git_deps.rs | 12 ++-- 53 files changed, 445 insertions(+), 534 deletions(-) delete mode 100644 src/bin/config_for_key.rs delete mode 100644 src/bin/config_list.rs diff --git a/src/bin/bench.rs b/src/bin/bench.rs index f8bf15ab9..7bd2100e5 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -1,8 +1,7 @@ use std::io::process::ExitStatus; use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError, Human}; +use cargo::util::{CliResult, CliError, Human, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -49,16 +48,16 @@ see the `cargo help pkgid` command. Compilation can be customized with the `bench` profile in the manifest. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - shell.set_verbose(options.flag_verbose); + config.shell().set_verbose(options.flag_verbose); - let mut ops = ops::TestOptions { + let ops = ops::TestOptions { name: options.flag_bench.as_ref().map(|s| s.as_slice()), no_run: options.flag_no_run, compile_opts: ops::CompileOptions { env: "bench", - shell: shell, + config: config, jobs: options.flag_jobs, target: options.flag_target.as_ref().map(|s| s.as_slice()), dev_deps: true, @@ -70,7 +69,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult }, }; - let err = try!(ops::run_benches(&root, &mut ops, + let err = try!(ops::run_benches(&root, &ops, options.arg_args.as_slice()).map_err(|err| { CliError::from_boxed(err, 101) })); diff --git a/src/bin/build.rs b/src/bin/build.rs index c6d35849b..96a6be5b5 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -1,10 +1,9 @@ use std::os; -use cargo::core::MultiShell; use cargo::ops::CompileOptions; use cargo::ops; use cargo::util::important_paths::{find_root_manifest_for_cwd}; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options { @@ -47,9 +46,9 @@ the manifest. The default profile for this command is `dev`, but passing the --release flag will use the `release` profile instead. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-build; args={:?}", os::args()); - shell.set_verbose(options.flag_verbose); + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); @@ -59,9 +58,9 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult "compile" }; - let mut opts = CompileOptions { + let opts = CompileOptions { env: env, - shell: shell, + config: config, jobs: options.flag_jobs, target: options.flag_target.as_ref().map(|t| t.as_slice()), dev_deps: false, @@ -72,7 +71,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult exec_engine: None, }; - ops::compile(&root, &mut opts).map(|_| None).map_err(|err| { + ops::compile(&root, &opts).map(|_| None).map_err(|err| { CliError::from_boxed(err, 101) }) } diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index 4d922090b..e0f9ca4eb 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -12,7 +12,7 @@ use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal}; use cargo::{execute_main_without_stdin, handle_error, shell}; use cargo::core::MultiShell; -use cargo::util::{CliError, CliResult, lev_distance}; +use cargo::util::{CliError, CliResult, lev_distance, Config}; #[derive(RustcDecodable)] struct Flags { @@ -56,8 +56,6 @@ macro_rules! each_subcommand{ ($mac:ident) => ({ $mac!(bench); $mac!(build); $mac!(clean); - $mac!(config_for_key); - $mac!(config_list); $mac!(doc); $mac!(fetch); $mac!(generate_lockfile); @@ -85,9 +83,9 @@ macro_rules! each_subcommand{ ($mac:ident) => ({ because they are fundamental (and intertwined). Other commands can rely on this top-level information. */ -fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult> { +fn execute(flags: Flags, config: &Config) -> CliResult> { debug!("executing; cmd=cargo; args={:?}", os::args()); - shell.set_verbose(flags.flag_verbose); + config.shell().set_verbose(flags.flag_verbose); if flags.flag_list { println!("Installed Commands:"); @@ -99,11 +97,11 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult> { let (mut args, command) = match flags.arg_command.as_slice() { "" | "help" if flags.arg_args.len() == 0 => { - shell.set_verbose(true); + config.shell().set_verbose(true); let args = &[os::args()[0].clone(), "-h".to_string()]; - let r = cargo::call_main_without_stdin(execute, shell, USAGE, args, + let r = cargo::call_main_without_stdin(execute, config, USAGE, args, false); - cargo::process_executed(r, shell); + cargo::process_executed(r, &mut **config.shell()); return Ok(None) } "help" if flags.arg_args[0].as_slice() == "-h" || @@ -118,18 +116,19 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult> { macro_rules! cmd{ ($name:ident) => ( if command.as_slice() == stringify!($name).replace("_", "-").as_slice() { mod $name; - shell.set_verbose(true); - let r = cargo::call_main_without_stdin($name::execute, shell, + config.shell().set_verbose(true); + let r = cargo::call_main_without_stdin($name::execute, config, $name::USAGE, args.as_slice(), false); - cargo::process_executed(r, shell); + cargo::process_executed(r, &mut **config.shell()); return Ok(None) } ) } each_subcommand!(cmd); - execute_subcommand(command.as_slice(), args.as_slice(), shell); + execute_subcommand(command.as_slice(), args.as_slice(), + &mut **config.shell()); Ok(None) } @@ -153,7 +152,8 @@ fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) { Some(command) => command, None => { let msg = match find_closest(cmd) { - Some(closest) => format!("No such subcommand\n\n\tDid you mean `{}`?\n", closest), + Some(closest) => format!("No such subcommand\n\n\t\ + Did you mean `{}`?\n", closest), None => "No such subcommand".to_string() }; return handle_error(CliError::new(msg, 127), shell) diff --git a/src/bin/clean.rs b/src/bin/clean.rs index f5550c6cb..dcc013e46 100644 --- a/src/bin/clean.rs +++ b/src/bin/clean.rs @@ -1,8 +1,7 @@ use std::os; use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -32,17 +31,17 @@ given, then all packages' artifacts are removed. For more information on SPEC and its format, see the `cargo help pkgid` command. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); debug!("executing; cmd=cargo-clean; args={:?}", os::args()); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - let mut opts = ops::CleanOptions { - shell: shell, + let opts = ops::CleanOptions { + config: config, spec: options.flag_package.as_ref().map(|s| s.as_slice()), target: options.flag_target.as_ref().map(|s| s.as_slice()), }; - ops::clean(&root, &mut opts).map(|_| None).map_err(|err| { + ops::clean(&root, &opts).map(|_| None).map_err(|err| { CliError::from_boxed(err, 101) }) } diff --git a/src/bin/config_for_key.rs b/src/bin/config_for_key.rs deleted file mode 100644 index 4b106592a..000000000 --- a/src/bin/config_for_key.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::os; -use std::collections::HashMap; - -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError, config}; - -#[derive(RustcDecodable)] -struct ConfigForKeyFlags { - flag_human: bool, - flag_key: String, -} - -#[derive(RustcEncodable)] -struct ConfigOut { - values: HashMap -} - -pub const USAGE: &'static str = " -Usage: - cargo config-for-key --human --key= - cargo config-for-key -h | --help - -Options: - -h, --help Print this message -"; - -pub fn execute(args: ConfigForKeyFlags, - _: &mut MultiShell) -> CliResult> { - let cwd = try!(os::getcwd().map_err(|_| - CliError::new("Couldn't determine the current working directory", 1))); - let value = try!(config::get_config(cwd, args.flag_key.as_slice()).map_err(|_| { - CliError::new("Couldn't load configuration", 1) - })); - - if args.flag_human { - println!("{:?}", value); - Ok(None) - } else { - let mut map = HashMap::new(); - map.insert(args.flag_key.clone(), value); - Ok(Some(ConfigOut { values: map })) - } -} diff --git a/src/bin/config_list.rs b/src/bin/config_list.rs deleted file mode 100644 index e267dbcd5..000000000 --- a/src/bin/config_list.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::os; -use std::collections::HashMap; - -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError, config}; - -#[derive(RustcDecodable)] -struct ConfigListFlags { - flag_human: bool, -} - -#[derive(RustcEncodable)] -struct ConfigOut { - values: HashMap -} - -pub const USAGE: &'static str = " -Usage: - cargo config-list --human - cargo config-list -h | --help - -Options: - -h, --help Print this message -"; - -pub fn execute(args: ConfigListFlags, - _: &mut MultiShell) -> CliResult> { - let cwd = try!(os::getcwd().map_err(|_| - CliError::new("Couldn't determine the current working directory", 1))); - let configs = try!(config::all_configs(cwd).map_err(|_| - CliError::new("Couldn't load configuration", 1))); - - if args.flag_human { - for (key, value) in configs.iter() { - println!("{} = {:?}", key, value); - } - Ok(None) - } else { - Ok(Some(ConfigOut { values: configs })) - } -} diff --git a/src/bin/doc.rs b/src/bin/doc.rs index 11f9823a8..d55567678 100644 --- a/src/bin/doc.rs +++ b/src/bin/doc.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::{MultiShell}; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -41,8 +40,8 @@ current package is documented. For more information on SPEC and its format, see the `cargo help pkgid` command. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); @@ -51,7 +50,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult open_result: options.flag_open, compile_opts: ops::CompileOptions { env: if options.flag_no_deps {"doc"} else {"doc-all"}, - shell: shell, + config: config, jobs: options.flag_jobs, target: None, dev_deps: false, diff --git a/src/bin/fetch.rs b/src/bin/fetch.rs index 98e33f3b4..a5afbf239 100644 --- a/src/bin/fetch.rs +++ b/src/bin/fetch.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::{MultiShell}; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::find_root_manifest_for_cwd; #[derive(RustcDecodable)] @@ -30,10 +29,10 @@ If the lockfile is not available, then this is the equivalent of all updated. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - try!(ops::fetch(&root, shell).map_err(|e| { + try!(ops::fetch(&root, config).map_err(|e| { CliError::from_boxed(e, 101) })); Ok(None) diff --git a/src/bin/generate_lockfile.rs b/src/bin/generate_lockfile.rs index c2e50ddb4..a350ab632 100644 --- a/src/bin/generate_lockfile.rs +++ b/src/bin/generate_lockfile.rs @@ -1,8 +1,7 @@ use std::os; use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::find_root_manifest_for_cwd; #[derive(RustcDecodable)] @@ -23,11 +22,11 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-generate-lockfile; args={:?}", os::args()); - shell.set_verbose(options.flag_verbose); + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - ops::generate_lockfile(&root, shell) + ops::generate_lockfile(&root, config) .map(|_| None).map_err(|err| CliError::from_boxed(err, 101)) } diff --git a/src/bin/git_checkout.rs b/src/bin/git_checkout.rs index 3e825ec3c..3fa251821 100644 --- a/src/bin/git_checkout.rs +++ b/src/bin/git_checkout.rs @@ -1,4 +1,3 @@ -use cargo::core::MultiShell; use cargo::core::source::{Source, SourceId, GitReference}; use cargo::sources::git::{GitSource}; use cargo::util::{Config, CliResult, CliError, human, ToUrl}; @@ -20,8 +19,8 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let Options { flag_url: url, flag_reference: reference, .. } = options; let url = try!(url.as_slice().to_url().map_err(|e| { @@ -33,10 +32,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult let reference = GitReference::Branch(reference.to_string()); let source_id = SourceId::for_git(&url, reference); - let mut config = try!(Config::new(shell, None, None).map_err(|e| { - CliError::from_boxed(e, 1) - })); - let mut source = GitSource::new(&source_id, &mut config); + let mut source = GitSource::new(&source_id, config); try!(source.update().map_err(|e| { CliError::new(format!("Couldn't update {:?}: {:?}", source, e), 1) diff --git a/src/bin/help.rs b/src/bin/help.rs index c21dbefeb..f07a1cc66 100644 --- a/src/bin/help.rs +++ b/src/bin/help.rs @@ -1,5 +1,4 @@ -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options; @@ -15,7 +14,7 @@ Options: -h, --help Print this message "; -pub fn execute(_: Options, _: &mut MultiShell) -> CliResult> { +pub fn execute(_: Options, _: &Config) -> CliResult> { // This is a dummy command just so that `cargo help help` works. // The actual delegation of help flag to subcommands is handled by the // cargo command. diff --git a/src/bin/locate_project.rs b/src/bin/locate_project.rs index 0644cb864..af2f45a60 100644 --- a/src/bin/locate_project.rs +++ b/src/bin/locate_project.rs @@ -1,5 +1,4 @@ -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError, human, ChainError}; +use cargo::util::{CliResult, CliError, human, ChainError, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -22,7 +21,7 @@ struct ProjectLocation { } pub fn execute(flags: LocateProjectFlags, - _: &mut MultiShell) -> CliResult> { + _: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(flags.flag_manifest_path)); let string = try!(root.as_str() diff --git a/src/bin/login.rs b/src/bin/login.rs index 6a164d4fe..bf3d707fd 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -1,7 +1,7 @@ use std::io; use cargo::ops; -use cargo::core::{MultiShell, SourceId, Source}; +use cargo::core::{SourceId, Source}; use cargo::sources::RegistrySource; use cargo::util::{CliResult, CliError, Config}; @@ -25,15 +25,14 @@ Options: "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let token = match options.arg_token.clone() { Some(token) => token, None => { let err = (|:| { - let config = try!(Config::new(shell, None, None)); - let src = try!(SourceId::for_central()); - let mut src = RegistrySource::new(&src, &config); + let src = try!(SourceId::for_central(config)); + let mut src = RegistrySource::new(&src, config); try!(src.update()); let config = try!(src.config()); let host = options.flag_host.clone().unwrap_or(config.api); @@ -48,7 +47,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult }; let token = token.as_slice().trim().to_string(); - try!(ops::registry_login(shell, token).map_err(|e| { + try!(ops::registry_login(config, token).map_err(|e| { CliError::from_boxed(e, 101) })); Ok(None) diff --git a/src/bin/new.rs b/src/bin/new.rs index e4c552643..e2412d1cf 100644 --- a/src/bin/new.rs +++ b/src/bin/new.rs @@ -1,8 +1,7 @@ use std::os; use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options { @@ -28,9 +27,9 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-new; args={:?}", os::args()); - shell.set_verbose(options.flag_verbose); + config.shell().set_verbose(options.flag_verbose); let Options { flag_bin, arg_path, flag_vcs, .. } = options; @@ -40,7 +39,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult bin: flag_bin, }; - ops::new(opts, shell).map(|_| None).map_err(|err| { + ops::new(opts, config).map(|_| None).map_err(|err| { CliError::from_boxed(err, 101) }) } diff --git a/src/bin/owner.rs b/src/bin/owner.rs index b0bfcc3f6..38edea893 100644 --- a/src/bin/owner.rs +++ b/src/bin/owner.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options { @@ -33,8 +32,8 @@ default). Note that owners of a package can upload new versions, yank old versions, and also modify the set of owners, so take caution! "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let opts = ops::OwnersOptions { krate: options.arg_crate, token: options.flag_token, @@ -43,7 +42,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult to_remove: options.flag_remove, list: options.flag_list, }; - try!(ops::modify_owners(shell, &opts).map_err(|e| { + try!(ops::modify_owners(config, &opts).map_err(|e| { CliError::from_boxed(e, 101) })); Ok(None) diff --git a/src/bin/package.rs b/src/bin/package.rs index d529ba087..444b114fb 100644 --- a/src/bin/package.rs +++ b/src/bin/package.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::{MultiShell}; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::find_root_manifest_for_cwd; #[derive(RustcDecodable)] @@ -28,10 +27,10 @@ Options: "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - ops::package(&root, shell, + ops::package(&root, config, !options.flag_no_verify, options.flag_list, !options.flag_no_metadata).map(|_| None).map_err(|err| { diff --git a/src/bin/pkgid.rs b/src/bin/pkgid.rs index 53f09b099..f0409b11f 100644 --- a/src/bin/pkgid.rs +++ b/src/bin/pkgid.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -43,12 +42,12 @@ Example Package IDs "; pub fn execute(options: Options, - shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); + config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path.clone())); let spec = options.arg_spec.as_ref().map(|s| s.as_slice()); - let spec = try!(ops::pkgid(&root, spec, shell).map_err(|err| { + let spec = try!(ops::pkgid(&root, spec, config).map_err(|err| { CliError::from_boxed(err, 101) })); println!("{}", spec); diff --git a/src/bin/publish.rs b/src/bin/publish.rs index 143272306..224c9a8b6 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::{MultiShell}; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::find_root_manifest_for_cwd; #[derive(RustcDecodable)] @@ -28,8 +27,8 @@ Options: "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let Options { flag_token: token, flag_host: host, @@ -39,7 +38,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult } = options; let root = try!(find_root_manifest_for_cwd(flag_manifest_path.clone())); - ops::publish(&root, shell, token, host, !no_verify).map(|_| None).map_err(|err| { + ops::publish(&root, config, token, host, !no_verify).map(|_| None).map_err(|err| { CliError::from_boxed(err, 101) }) } diff --git a/src/bin/read_manifest.rs b/src/bin/read_manifest.rs index fe8d88be0..4bf330360 100644 --- a/src/bin/read_manifest.rs +++ b/src/bin/read_manifest.rs @@ -1,5 +1,5 @@ -use cargo::core::{MultiShell, Package, Source}; -use cargo::util::{CliResult, CliError}; +use cargo::core::{Package, Source}; +use cargo::util::{CliResult, CliError, Config}; use cargo::sources::{PathSource}; #[derive(RustcDecodable)] @@ -17,9 +17,9 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(options: Options, _: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { let path = Path::new(options.flag_manifest_path.as_slice()); - let mut source = try!(PathSource::for_path(&path).map_err(|e| { + let mut source = try!(PathSource::for_path(&path, config).map_err(|e| { CliError::new(e.description(), 1) })); diff --git a/src/bin/run.rs b/src/bin/run.rs index 42456d1a9..40e94f578 100644 --- a/src/bin/run.rs +++ b/src/bin/run.rs @@ -1,9 +1,8 @@ use std::io::process::ExitStatus; use cargo::ops; -use cargo::core::{MultiShell}; use cargo::core::manifest::TargetKind; -use cargo::util::{CliResult, CliError, human}; +use cargo::util::{CliResult, CliError, human, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -46,8 +45,8 @@ and `--example` specifies the example target to run. At most one of `--bin` or All of the trailing arguments are passed as to the binary to run. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); let env = match (options.flag_release, options.flag_example.is_some()) { @@ -56,9 +55,9 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult (false, false) => "compile" }; - let mut compile_opts = ops::CompileOptions { + let compile_opts = ops::CompileOptions { env: env, - shell: shell, + config: config, jobs: options.flag_jobs, target: options.flag_target.as_ref().map(|t| t.as_slice()), dev_deps: true, @@ -80,7 +79,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult let err = try!(ops::run(&root, target_kind, name, - &mut compile_opts, + &compile_opts, options.arg_args.as_slice()).map_err(|err| { CliError::from_boxed(err, 101) })); diff --git a/src/bin/search.rs b/src/bin/search.rs index a973d14f6..27901d6ea 100644 --- a/src/bin/search.rs +++ b/src/bin/search.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::{MultiShell}; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options { @@ -21,15 +20,15 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); let Options { flag_host: host, arg_query: query, .. } = options; - ops::search(query.as_slice(), shell, host) + ops::search(query.as_slice(), config, host) .map(|_| None) .map_err(|err| CliError::from_boxed(err, 101)) } diff --git a/src/bin/test.rs b/src/bin/test.rs index a723210fd..6d20f54f8 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -1,8 +1,7 @@ use std::io::process::ExitStatus; use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError, Human}; +use cargo::util::{CliResult, CliError, Human, Config}; use cargo::util::important_paths::{find_root_manifest_for_cwd}; #[derive(RustcDecodable)] @@ -51,16 +50,16 @@ current package is tested. For more information on SPEC and its format, see the Compilation can be configured via the `test` profile in the manifest. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - shell.set_verbose(options.flag_verbose); + config.shell().set_verbose(options.flag_verbose); - let mut ops = ops::TestOptions { + let ops = ops::TestOptions { name: options.flag_test.as_ref().map(|s| s.as_slice()), no_run: options.flag_no_run, compile_opts: ops::CompileOptions { env: "test", - shell: shell, + config: config, jobs: options.flag_jobs, target: options.flag_target.as_ref().map(|s| s.as_slice()), dev_deps: true, @@ -72,7 +71,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult }, }; - let err = try!(ops::run_tests(&root, &mut ops, + let err = try!(ops::run_tests(&root, &ops, options.arg_args.as_slice()).map_err(|err| { CliError::from_boxed(err, 101) })); diff --git a/src/bin/update.rs b/src/bin/update.rs index 005ea53fb..fa75506bc 100644 --- a/src/bin/update.rs +++ b/src/bin/update.rs @@ -1,13 +1,11 @@ use std::os; use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; use cargo::util::important_paths::find_root_manifest_for_cwd; #[derive(RustcDecodable)] struct Options { - arg_spec: Option, flag_package: Option, flag_aggressive: bool, flag_precise: Option, @@ -20,7 +18,6 @@ Update dependencies as recorded in the local lock file. Usage: cargo update [options] - cargo update [options] Options: -h, --help Print this message @@ -51,28 +48,21 @@ updated. For more information about package id specifications, see `cargo help pkgid`. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { +pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-update; args={:?}", os::args()); - shell.set_verbose(options.flag_verbose); + config.shell().set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - let spec = if options.arg_spec.is_some() { - let _ = shell.warn("`cargo update foo` has been deprecated in favor \ - of `cargo update -p foo`. This functionality \ - will be removed in the future"); - options.arg_spec.as_ref() - } else { - options.flag_package.as_ref() - }; + let spec = options.flag_package.as_ref(); - let mut update_opts = ops::UpdateOptions { + let update_opts = ops::UpdateOptions { aggressive: options.flag_aggressive, precise: options.flag_precise.as_ref().map(|s| s.as_slice()), to_update: spec.map(|s| s.as_slice()), - shell: shell, + config: config, }; - ops::update_lockfile(&root, &mut update_opts) + ops::update_lockfile(&root, &update_opts) .map(|_| None).map_err(|err| CliError::from_boxed(err, 101)) } diff --git a/src/bin/verify_project.rs b/src/bin/verify_project.rs index 5445bc919..95fffab57 100644 --- a/src/bin/verify_project.rs +++ b/src/bin/verify_project.rs @@ -4,8 +4,7 @@ use std::collections::HashMap; use std::io::File; use std::os; -use cargo::core::MultiShell; -use cargo::util::CliResult; +use cargo::util::{CliResult, Config}; pub type Error = HashMap; @@ -26,9 +25,8 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(args: Flags, - shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(args.flag_verbose); +pub fn execute(args: Flags, config: &Config) -> CliResult> { + config.shell().set_verbose(args.flag_verbose); let file = Path::new(args.flag_manifest_path); let contents = match File::open(&file).read_to_string() { diff --git a/src/bin/version.rs b/src/bin/version.rs index ab212987e..e1bc0116f 100644 --- a/src/bin/version.rs +++ b/src/bin/version.rs @@ -1,8 +1,7 @@ use std::os; use cargo; -use cargo::core::MultiShell; -use cargo::util::CliResult; +use cargo::util::{CliResult, Config}; #[derive(RustcDecodable)] struct Options; @@ -16,7 +15,7 @@ Options: -v, --verbose Use verbose output "; -pub fn execute(_: Options, _: &mut MultiShell) -> CliResult> { +pub fn execute(_: Options, _: &Config) -> CliResult> { debug!("executing; cmd=cargo-version; args={:?}", os::args()); println!("{}", cargo::version()); diff --git a/src/bin/yank.rs b/src/bin/yank.rs index e79deabe7..90cf677f1 100644 --- a/src/bin/yank.rs +++ b/src/bin/yank.rs @@ -1,6 +1,5 @@ use cargo::ops; -use cargo::core::MultiShell; -use cargo::util::{CliResult, CliError}; +use cargo::util::{CliResult, CliError, Config}; #[derive(RustcDecodable)] struct Options { @@ -35,9 +34,9 @@ download the yanked version to use it. Cargo will, however, not allow any new crates to be locked to any yanked version. "; -pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { - shell.set_verbose(options.flag_verbose); - try!(ops::yank(shell, +pub fn execute(options: Options, config: &Config) -> CliResult> { + config.shell().set_verbose(options.flag_verbose); + try!(ops::yank(config, options.arg_crate, options.flag_vers, options.flag_token, diff --git a/src/cargo/core/package_id_spec.rs b/src/cargo/core/package_id_spec.rs index d688b6e45..ba028b5e8 100644 --- a/src/cargo/core/package_id_spec.rs +++ b/src/cargo/core/package_id_spec.rs @@ -161,6 +161,7 @@ impl fmt::String for PackageIdSpec { mod tests { use core::{PackageId, SourceId}; use super::{PackageIdSpec, url}; + use url::Url; use semver::Version; #[test] @@ -223,7 +224,8 @@ mod tests { #[test] fn matching() { - let sid = SourceId::for_central().unwrap(); + let url = Url::parse("http://example.com").unwrap(); + let sid = SourceId::for_registry(&url); let foo = PackageId::new("foo", "1.2.3", &sid).unwrap(); let bar = PackageId::new("bar", "1.2.3", &sid).unwrap(); diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 65f122943..2ff375e38 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -36,9 +36,9 @@ impl Registry for Vec { /// `SourceMap` structure contained within which is a mapping of a `SourceId` to /// a `Source`. Each `Source` in the map has been updated (using network /// operations if necessary) and is ready to be queried for packages. -pub struct PackageRegistry<'a> { +pub struct PackageRegistry<'a, 'b: 'a> { sources: SourceMap<'a>, - config: &'a Config<'a>, + config: &'a Config<'b>, // A list of sources which are considered "overrides" which take precedent // when querying for packages. @@ -71,8 +71,8 @@ enum Kind { Normal, } -impl<'a> PackageRegistry<'a> { - pub fn new(config: &'a Config<'a>) -> PackageRegistry<'a> { +impl<'a, 'b> PackageRegistry<'a, 'b> { + pub fn new(config: &'a Config<'b>) -> PackageRegistry<'a, 'b> { PackageRegistry { sources: SourceMap::new(), source_ids: HashMap::new(), @@ -276,7 +276,7 @@ impl<'a> PackageRegistry<'a> { } } -impl<'a> Registry for PackageRegistry<'a> { +impl<'a, 'b> Registry for PackageRegistry<'a, 'b> { fn query(&mut self, dep: &Dependency) -> CargoResult> { let overrides = try!(self.query_overrides(dep)); diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs index 88ab4e1b0..72252788c 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source.rs @@ -176,8 +176,8 @@ impl SourceId { /// /// This is the main cargo registry by default, but it can be overridden in /// a `.cargo/config`. - pub fn for_central() -> CargoResult { - Ok(SourceId::for_registry(&try!(RegistrySource::url()))) + pub fn for_central(config: &Config) -> CargoResult { + Ok(SourceId::for_registry(&try!(RegistrySource::url(config)))) } pub fn get_url(&self) -> &Url { &self.inner.url } @@ -201,7 +201,7 @@ impl SourceId { Ok(p) => p, Err(()) => panic!("path sources cannot be remote"), }; - Box::new(PathSource::new(&path, self)) as Box + Box::new(PathSource::new(&path, self, config)) as Box }, Kind::Registry => { Box::new(RegistrySource::new(self, config)) as Box diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 7c07021eb..cd3dc898a 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -33,7 +33,7 @@ use docopt::Docopt; use core::{Shell, MultiShell, ShellConfig}; use term::color::{BLACK, RED}; -pub use util::{CargoError, CliError, CliResult, human}; +pub use util::{CargoError, CliError, CliResult, human, Config}; macro_rules! some { ($e:expr) => ( @@ -58,7 +58,7 @@ pub mod sources; pub mod util; pub fn execute_main( - exec: fn(T, U, &mut MultiShell) -> CliResult>, + exec: fn(T, U, &Config) -> CliResult>, options_first: bool, usage: &str) where V: Encodable, T: Decodable, U: Decodable @@ -69,8 +69,8 @@ pub fn execute_main( } pub fn call_main( - exec: fn(T, U, &mut MultiShell) -> CliResult>, - shell: &mut MultiShell, + exec: fn(T, U, &Config) -> CliResult>, + shell: &Config, usage: &str, args: &[String], options_first: bool) -> CliResult> @@ -83,7 +83,7 @@ pub fn call_main( } pub fn execute_main_without_stdin( - exec: fn(T, &mut MultiShell) -> CliResult>, + exec: fn(T, &Config) -> CliResult>, options_first: bool, usage: &str) where V: Encodable, T: Decodable @@ -93,23 +93,9 @@ pub fn execute_main_without_stdin( }); } -pub fn execute_main_with_args_and_without_stdin( - exec: fn(T, &mut MultiShell) -> CliResult>, - options_first: bool, - usage: &str, - args: &[String]) - where V: Encodable, T: Decodable -{ - let mut shell = shell(true); - - process_executed( - call_main_without_stdin(exec, &mut shell, usage, args, options_first), - &mut shell) -} - pub fn call_main_without_stdin( - exec: fn(T, &mut MultiShell) -> CliResult>, - shell: &mut MultiShell, + exec: fn(T, &Config) -> CliResult>, + shell: &Config, usage: &str, args: &[String], options_first: bool) -> CliResult> @@ -120,15 +106,19 @@ pub fn call_main_without_stdin( } fn process(mut callback: F) - where F: FnMut(&[String], &mut MultiShell) -> CliResult>, + where F: FnMut(&[String], &Config) -> CliResult>, V: Encodable { let mut shell = shell(true); - process_executed(callback(os::args().as_slice(), &mut shell), &mut shell) + process_executed({ + match Config::new(&mut shell) { + Ok(cfg) => callback(os::args().as_slice(), &cfg), + Err(e) => Err(CliError::from_boxed(e, 101)), + } + }, &mut shell) } -pub fn process_executed(result: CliResult>, - shell: &mut MultiShell) +pub fn process_executed(result: CliResult>, shell: &mut MultiShell) where T: Encodable { match result { diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 45f1d4d17..592dbab56 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -1,21 +1,22 @@ use std::default::Default; use std::io::fs::{self, PathExtensions}; -use core::{MultiShell, PackageSet}; +use core::PackageSet; use core::source::{Source, SourceMap}; use sources::PathSource; use util::{CargoResult, human, ChainError, Config}; use ops::{self, Layout, Context}; -pub struct CleanOptions<'a> { +pub struct CleanOptions<'a, 'b: 'a> { pub spec: Option<&'a str>, pub target: Option<&'a str>, - pub shell: &'a mut MultiShell, + pub config: &'a Config<'b>, } /// Cleans the project from build artifacts. -pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> { - let mut src = try!(PathSource::for_path(&manifest_path.dir_path())); +pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> { + let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), + opts.config)); try!(src.update()); let root = try!(src.get_root_package()); let manifest = root.get_manifest(); @@ -37,9 +38,8 @@ pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> { let pkgid = try!(resolve.query(spec)); // Translate the PackageId to a Package - let mut cfg = try!(Config::new(opts.shell, None, None)); let pkg = { - let mut source = pkgid.get_source_id().load(&mut cfg); + let mut source = pkgid.get_source_id().load(opts.config); try!(source.update()); (try!(source.get(&[pkgid.clone()]))).into_iter().next().unwrap() }; @@ -48,7 +48,7 @@ pub fn clean(manifest_path: &Path, opts: &mut CleanOptions) -> CargoResult<()> { // filenames and such let srcs = SourceMap::new(); let pkgs = PackageSet::new(&[]); - let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, &mut cfg, + let cx = try!(Context::new("compile", &resolve, &srcs, &pkgs, opts.config, Layout::at(root.get_absolute_target_dir()), None, &pkg, Default::default())); diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 4da2ad92b..ec002d943 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -28,7 +28,7 @@ use std::default::Default; use std::sync::Arc; use core::registry::PackageRegistry; -use core::{MultiShell, Source, SourceId, PackageSet, Package, Target, PackageId}; +use core::{Source, SourceId, PackageSet, Package, Target, PackageId}; use core::resolver::Method; use ops::{self, BuildOutput, ExecEngine}; use sources::{PathSource}; @@ -36,9 +36,9 @@ use util::config::{Config, ConfigValue}; use util::{CargoResult, config, internal, human, ChainError, profile}; /// Contains informations about how a package should be compiled. -pub struct CompileOptions<'a> { +pub struct CompileOptions<'a, 'b: 'a> { pub env: &'a str, - pub shell: &'a mut MultiShell, + pub config: &'a Config<'b>, /// Number of concurrent jobs to use. pub jobs: Option, /// The target platform to compile for (example: `i686-unknown-linux-gnu`). @@ -53,11 +53,12 @@ pub struct CompileOptions<'a> { } pub fn compile(manifest_path: &Path, - options: &mut CompileOptions) + options: &CompileOptions) -> CargoResult { log!(4, "compile; manifest-path={}", manifest_path.display()); - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + options.config)); try!(source.update()); // TODO: Move this into PathSource @@ -65,16 +66,16 @@ pub fn compile(manifest_path: &Path, debug!("loaded package; package={}", package); for key in package.get_manifest().get_warnings().iter() { - try!(options.shell.warn(key)) + try!(options.config.shell().warn(key)) } compile_pkg(&package, options) } -pub fn compile_pkg(package: &Package, options: &mut CompileOptions) +pub fn compile_pkg(package: &Package, options: &CompileOptions) -> CargoResult { - let CompileOptions { env, ref mut shell, jobs, target, spec, + let CompileOptions { env, config, jobs, target, spec, dev_deps, features, no_default_features, - lib_only, ref mut exec_engine } = *options; + lib_only, ref exec_engine } = *options; let target = target.map(|s| s.to_string()); let features = features.iter().flat_map(|s| { @@ -85,15 +86,16 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions) return Err(human("features cannot be modified when the main package \ is not being built")) } + if jobs == Some(0) { + return Err(human("jobs must be at least 1")) + } - let user_configs = try!(config::all_configs(try!(os::getcwd()))); - let override_ids = try!(source_ids_from_config(&user_configs, + let override_ids = try!(source_ids_from_config(config, package.get_root())); - let config = try!(Config::new(*shell, jobs, target.clone())); let (packages, resolve_with_overrides, sources) = { let rustc_host = config.rustc_host().to_string(); - let mut registry = PackageRegistry::new(&config); + let mut registry = PackageRegistry::new(config); // First, resolve the package's *listed* dependencies, as well as // downloading and updating all remotes and such. @@ -147,21 +149,22 @@ pub fn compile_pkg(package: &Package, options: &mut CompileOptions) let ret = { let _p = profile::start("compiling"); - let lib_overrides = try!(scrape_build_config(&config, &user_configs)); + let lib_overrides = try!(scrape_build_config(config, jobs, target)); try!(ops::compile_targets(env.as_slice(), targets.as_slice(), to_build, &PackageSet::new(packages.as_slice()), &resolve_with_overrides, &sources, - &config, lib_overrides, exec_engine.clone())) + config, lib_overrides, exec_engine.clone())) }; return Ok(ret); } -fn source_ids_from_config(configs: &HashMap, - cur_path: Path) -> CargoResult> { - debug!("loaded config; configs={:?}", configs); +fn source_ids_from_config(config: &Config, cur_path: Path) + -> CargoResult> { + let configs = try!(config.values()); + debug!("loaded config; configs={:?}", configs); let config_paths = match configs.get("paths") { Some(cfg) => cfg, None => return Ok(Vec::new()) @@ -183,21 +186,27 @@ fn source_ids_from_config(configs: &HashMap, } fn scrape_build_config(config: &Config, - configs: &HashMap) - -> CargoResult { - let target = match configs.get("target") { - None => return Ok(Default::default()), + jobs: Option, + target: Option) -> CargoResult { + let configs = try!(config.values()); + let mut base = ops::BuildConfig { + jobs: jobs.unwrap_or(os::num_cpus() as u32), + requested_target: target.clone(), + ..Default::default() + }; + let target_config = match configs.get("target") { + None => return Ok(base), Some(target) => try!(target.table().chain_error(|| { internal("invalid configuration for the key `target`") })), }; - let host = try!(scrape_target_config(target, config.rustc_host())); - let target = match config.target() { - Some(triple) => try!(scrape_target_config(target, triple)), - None => host.clone(), + base.host = try!(scrape_target_config(target_config, config.rustc_host())); + base.target = match target.as_ref() { + Some(triple) => try!(scrape_target_config(target_config, &triple[])), + None => base.host.clone(), }; - Ok(ops::BuildConfig { host: host, target: target }) + Ok(base) } fn scrape_target_config(target: &HashMap, diff --git a/src/cargo/ops/cargo_doc.rs b/src/cargo/ops/cargo_doc.rs index 2e7831440..251e9e26f 100644 --- a/src/cargo/ops/cargo_doc.rs +++ b/src/cargo/ops/cargo_doc.rs @@ -8,15 +8,16 @@ use sources::PathSource; use std::io::process::Command; use util::{CargoResult, human}; -pub struct DocOptions<'a> { +pub struct DocOptions<'a, 'b: 'a> { pub all: bool, pub open_result: bool, - pub compile_opts: ops::CompileOptions<'a>, + pub compile_opts: ops::CompileOptions<'a, 'b>, } pub fn doc(manifest_path: &Path, - options: &mut DocOptions) -> CargoResult<()> { - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + options: &DocOptions) -> CargoResult<()> { + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + options.compile_opts.config)); try!(source.update()); let package = try!(source.get_root_package()); @@ -40,7 +41,7 @@ pub fn doc(manifest_path: &Path, } } - try!(ops::compile(manifest_path, &mut options.compile_opts)); + try!(ops::compile(manifest_path, &options.compile_opts)); if options.open_result { let name = match options.compile_opts.spec { diff --git a/src/cargo/ops/cargo_fetch.rs b/src/cargo/ops/cargo_fetch.rs index 4c4cb0ebf..44ef632bf 100644 --- a/src/cargo/ops/cargo_fetch.rs +++ b/src/cargo/ops/cargo_fetch.rs @@ -1,4 +1,3 @@ -use core::MultiShell; use core::registry::PackageRegistry; use core::source::Source; use ops; @@ -6,14 +5,13 @@ use sources::PathSource; use util::{CargoResult, Config}; /// Executes `cargo fetch`. -pub fn fetch(manifest_path: &Path, - shell: &mut MultiShell) -> CargoResult<()> { - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); +pub fn fetch(manifest_path: &Path, config: &Config) -> CargoResult<()> { + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(source.update()); let package = try!(source.get_root_package()); - let mut config = try!(Config::new(shell, None, None)); - let mut registry = PackageRegistry::new(&mut config); + let mut registry = PackageRegistry::new(config); try!(ops::resolve_pkg(&mut registry, &package)); Ok(()) } diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index 47d987f9f..91de74327 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -2,28 +2,27 @@ use std::collections::HashSet; use core::PackageId; use core::registry::PackageRegistry; -use core::{MultiShell, Source, Resolve}; +use core::{Source, Resolve}; use core::resolver::Method; use ops; use sources::{PathSource}; use util::config::{Config}; use util::{CargoResult, human}; -pub struct UpdateOptions<'a> { - pub shell: &'a mut MultiShell, +pub struct UpdateOptions<'a, 'b: 'a> { + pub config: &'a Config<'b>, pub to_update: Option<&'a str>, pub precise: Option<&'a str>, pub aggressive: bool, } -pub fn generate_lockfile(manifest_path: &Path, - shell: &mut MultiShell) +pub fn generate_lockfile(manifest_path: &Path, config: &Config) -> CargoResult<()> { - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(source.update()); let package = try!(source.get_root_package()); - let mut config = try!(Config::new(shell, None, None)); - let mut registry = PackageRegistry::new(&mut config); + let mut registry = PackageRegistry::new(config); let resolve = try!(ops::resolve_with_previous(&mut registry, &package, Method::Everything, None, None)); @@ -32,8 +31,9 @@ pub fn generate_lockfile(manifest_path: &Path, } pub fn update_lockfile(manifest_path: &Path, - opts: &mut UpdateOptions) -> CargoResult<()> { - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + opts: &UpdateOptions) -> CargoResult<()> { + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + opts.config)); try!(source.update()); let package = try!(source.get_root_package()); @@ -47,8 +47,7 @@ pub fn update_lockfile(manifest_path: &Path, simultaneously")) } - let mut config = try!(Config::new(opts.shell, None, None)); - let mut registry = PackageRegistry::new(&mut config); + let mut registry = PackageRegistry::new(opts.config); let mut to_avoid = HashSet::new(); match opts.to_update { diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index 26ddad9b3..9649fffd4 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -4,10 +4,10 @@ use std::io::fs::PathExtensions; use rustc_serialize::{Decodable, Decoder}; -use git2::Config; +use git2::Config as GitConfig; -use util::{GitRepo, HgRepo, CargoResult, human, ChainError, config, internal}; -use core::shell::MultiShell; +use util::{GitRepo, HgRepo, CargoResult, human, ChainError, internal}; +use util::Config; #[derive(Copy, Show, PartialEq)] pub enum VersionControl { Git, Hg, NoVcs } @@ -38,8 +38,8 @@ struct CargoNewConfig { version_control: Option, } -pub fn new(opts: NewOptions, _shell: &mut MultiShell) -> CargoResult<()> { - let path = try!(os::getcwd()).join(opts.path); +pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> { + let path = config.cwd().join(opts.path); if path.exists() { return Err(human(format!("Destination `{}` already exists", path.display()))) @@ -51,7 +51,7 @@ pub fn new(opts: NewOptions, _shell: &mut MultiShell) -> CargoResult<()> { return Err(human(format!("Invalid character `{}` in crate name: `{}`", c, name).as_slice())); } - mk(&path, name, &opts).chain_error(|| { + mk(config, &path, name, &opts).chain_error(|| { human(format!("Failed to create project `{}` at `{}`", name, path.display())) }) @@ -61,8 +61,9 @@ fn existing_vcs_repo(path: &Path) -> bool { GitRepo::discover(path).is_ok() || HgRepo::discover(path).is_ok() } -fn mk(path: &Path, name: &str, opts: &NewOptions) -> CargoResult<()> { - let cfg = try!(global_config()); +fn mk(config: &Config, path: &Path, name: &str, + opts: &NewOptions) -> CargoResult<()> { + let cfg = try!(global_config(config)); let mut ignore = "/target\n".to_string(); let in_existing_vcs_repo = existing_vcs_repo(&path.dir_path()); if !opts.bin { @@ -129,7 +130,7 @@ fn it_works() { } fn discover_author() -> CargoResult<(String, Option)> { - let git_config = Config::open_default().ok(); + let git_config = GitConfig::open_default().ok(); let git_config = git_config.as_ref(); let name = git_config.and_then(|g| g.get_str("user.name").ok()) .map(|s| s.to_string()) @@ -151,8 +152,8 @@ fn discover_author() -> CargoResult<(String, Option)> { Ok((name, email)) } -fn global_config() -> CargoResult { - let user_configs = try!(config::all_configs(try!(os::getcwd()))); +fn global_config(config: &Config) -> CargoResult { + let user_configs = try!(config.values()); let mut cfg = CargoNewConfig { name: None, email: None, diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 0ff3d8760..e158ccd31 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -7,9 +7,9 @@ use flate2::{GzBuilder, BestCompression}; use flate2::reader::GzDecoder; use core::source::{Source, SourceId}; -use core::{Package, MultiShell}; +use core::Package; use sources::PathSource; -use util::{CargoResult, human, internal, ChainError}; +use util::{CargoResult, human, internal, ChainError, Config}; use ops; struct Bomb { path: Option } @@ -24,16 +24,17 @@ impl Drop for Bomb { } pub fn package(manifest_path: &Path, - shell: &mut MultiShell, + config: &Config, verify: bool, list: bool, metadata: bool) -> CargoResult> { - let mut src = try!(PathSource::for_path(&manifest_path.dir_path())); + let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(src.update()); let pkg = try!(src.get_root_package()); if metadata { - try!(check_metadata(&pkg, shell)); + try!(check_metadata(&pkg, config)); } if list { @@ -55,12 +56,12 @@ pub fn package(manifest_path: &Path, let mut bomb = Bomb { path: Some(dst.clone()) }; - try!(shell.status("Packaging", pkg.get_package_id().to_string())); - try!(tar(&pkg, &src, shell, &dst).chain_error(|| { + try!(config.shell().status("Packaging", pkg.get_package_id().to_string())); + try!(tar(&pkg, &src, config, &dst).chain_error(|| { human("failed to prepare local package for uploading") })); if verify { - try!(run_verify(&pkg, shell, &dst).chain_error(|| { + try!(run_verify(config, &pkg, &dst).chain_error(|| { human("failed to verify package tarball") })) } @@ -69,7 +70,7 @@ pub fn package(manifest_path: &Path, // check that the package has some piece of metadata that a human can // use to tell what the package is about. -fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> { +fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> { let md = pkg.get_manifest().get_metadata(); let mut missing = vec![]; @@ -93,7 +94,7 @@ fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> { } things.push_str(missing.last().unwrap().as_slice()); - try!(shell.warn( + try!(config.shell().warn( format!("warning: manifest has no {things}. \ See http://doc.crates.io/manifest.html#package-metadata for more info.", things = things).as_slice())) @@ -101,7 +102,7 @@ fn check_metadata(pkg: &Package, shell: &mut MultiShell) -> CargoResult<()> { Ok(()) } -fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell, +fn tar(pkg: &Package, src: &PathSource, config: &Config, dst: &Path) -> CargoResult<()> { if dst.exists() { @@ -128,7 +129,7 @@ fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell, relative.display())) })); let mut file = try!(File::open(file)); - try!(shell.verbose(|shell| { + try!(config.shell().verbose(|shell| { shell.status("Archiving", relative.as_slice()) })); let path = format!("{}-{}{}{}", pkg.get_name(), @@ -141,9 +142,9 @@ fn tar(pkg: &Package, src: &PathSource, shell: &mut MultiShell, Ok(()) } -fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path) +fn run_verify(config: &Config, pkg: &Package, tar: &Path) -> CargoResult<()> { - try!(shell.status("Verifying", pkg)); + try!(config.shell().status("Verifying", pkg)); let f = try!(GzDecoder::new(try!(File::open(tar)))); let dst = pkg.get_root().join(format!("target/package/{}-{}", @@ -158,7 +159,7 @@ fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path) // When packages are uploaded to the registry, all path dependencies are // implicitly converted to registry-based dependencies, so we rewrite those // dependencies here. - let registry = try!(SourceId::for_central()); + let registry = try!(SourceId::for_central(config)); let new_summary = pkg.get_summary().clone().map_dependencies(|d| { if !d.get_source_id().is_path() { return d } d.source_id(registry.clone()) @@ -170,9 +171,9 @@ fn run_verify(pkg: &Package, shell: &mut MultiShell, tar: &Path) pkg.get_package_id().get_source_id()); // Now that we've rewritten all our path dependencies, compile it! - try!(ops::compile_pkg(&new_pkg, &mut ops::CompileOptions { + try!(ops::compile_pkg(&new_pkg, &ops::CompileOptions { env: "compile", - shell: shell, + config: config, jobs: None, target: None, dev_deps: false, diff --git a/src/cargo/ops/cargo_pkgid.rs b/src/cargo/ops/cargo_pkgid.rs index 3b39bb0e7..f32484457 100644 --- a/src/cargo/ops/cargo_pkgid.rs +++ b/src/cargo/ops/cargo_pkgid.rs @@ -1,12 +1,13 @@ use ops; -use core::{MultiShell, Source, PackageIdSpec}; +use core::{Source, PackageIdSpec}; use sources::{PathSource}; -use util::{CargoResult, human}; +use util::{CargoResult, human, Config}; pub fn pkgid(manifest_path: &Path, spec: Option<&str>, - _shell: &mut MultiShell) -> CargoResult { - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + config: &Config) -> CargoResult { + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(source.update()); let package = try!(source.get_root_package()); diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index 3c5f5b603..9314736d9 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -1,37 +1,38 @@ use std::collections::HashSet; -use std::io::{self, File, fs}; +use std::error::FromError; use std::io::fs::PathExtensions; +use std::io::{self, File, fs}; use core::{Package,Manifest,SourceId}; -use util::{self, CargoResult, human}; +use util::{self, CargoResult, human, Config}; use util::important_paths::find_project_manifest_exact; use util::toml::{Layout, project_layout}; -use std::error::FromError; -pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId) +pub fn read_manifest(contents: &[u8], layout: Layout, source_id: &SourceId, + config: &Config) -> CargoResult<(Manifest, Vec)> { let root = layout.root.clone(); - util::toml::to_manifest(contents, source_id, layout).map_err(|e| { + util::toml::to_manifest(contents, source_id, layout, config).map_err(|e| { human(format!("failed to parse manifest at `{:?}`\n{}", root.join("Cargo.toml"), e)) }) } -pub fn read_package(path: &Path, source_id: &SourceId) - -> CargoResult<(Package, Vec)> { +pub fn read_package(path: &Path, source_id: &SourceId, config: &Config) + -> CargoResult<(Package, Vec)> { log!(5, "read_package; path={}; source-id={}", path.display(), source_id); let mut file = try!(File::open(path)); let data = try!(file.read_to_end()); let layout = project_layout(&path.dir_path()); let (manifest, nested) = - try!(read_manifest(data.as_slice(), layout, source_id)); + try!(read_manifest(data.as_slice(), layout, source_id, config)); Ok((Package::new(manifest, path, source_id), nested)) } -pub fn read_packages(path: &Path, - source_id: &SourceId) -> CargoResult> { +pub fn read_packages(path: &Path, source_id: &SourceId, config: &Config) + -> CargoResult> { let mut all_packages = HashSet::new(); let mut visited = HashSet::::new(); @@ -52,7 +53,7 @@ pub fn read_packages(path: &Path, } if has_manifest(dir) { - try!(read_nested_packages(dir, &mut all_packages, source_id, + try!(read_nested_packages(dir, &mut all_packages, source_id, config, &mut visited)); } Ok(true) @@ -104,12 +105,13 @@ fn has_manifest(path: &Path) -> bool { fn read_nested_packages(path: &Path, all_packages: &mut HashSet, source_id: &SourceId, + config: &Config, visited: &mut HashSet) -> CargoResult<()> { if !visited.insert(path.clone()) { return Ok(()) } let manifest = try!(find_project_manifest_exact(path, "Cargo.toml")); - let (pkg, nested) = try!(read_package(&manifest, source_id)); + let (pkg, nested) = try!(read_package(&manifest, source_id, config)); all_packages.insert(pkg); // Registry sources are not allowed to have `path=` dependencies because @@ -117,7 +119,7 @@ fn read_nested_packages(path: &Path, if !source_id.is_registry() { for p in nested.iter() { try!(read_nested_packages(&path.join(p), all_packages, source_id, - visited)); + config, visited)); } } diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index 772828c23..0ef3986a9 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -9,9 +9,10 @@ use sources::PathSource; pub fn run(manifest_path: &Path, target_kind: TargetKind, name: Option, - options: &mut ops::CompileOptions, + options: &ops::CompileOptions, args: &[String]) -> CargoResult> { - let mut src = try!(PathSource::for_path(&manifest_path.dir_path())); + let config = options.config; + let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), config)); try!(src.update()); let root = try!(src.get_root_package()); let env = options.env; @@ -56,6 +57,6 @@ pub fn run(manifest_path: &Path, .args(args) .cwd(try!(os::getcwd())); - try!(options.shell.status("Running", process.to_string())); + try!(config.shell().status("Running", process.to_string())); Ok(process.exec().err()) } diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 41dca8dbd..1a6c08c03 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -1,6 +1,5 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::HashMap; -use std::os; use std::str; use std::sync::Arc; @@ -24,13 +23,12 @@ pub enum Platform { } pub struct Context<'a, 'b: 'a> { - pub config: &'b Config<'b>, + pub config: &'a Config<'b>, pub resolve: &'a Resolve, - pub sources: &'a SourceMap<'b>, + pub sources: &'a SourceMap<'a>, pub compilation: Compilation, pub build_state: Arc, pub exec_engine: Arc>, - pub cwd: Path, env: &'a str, host: Layout, @@ -46,30 +44,29 @@ pub struct Context<'a, 'b: 'a> { } impl<'a, 'b: 'a> Context<'a, 'b> { - pub fn new(env: &'a str, resolve: &'a Resolve, sources: &'a SourceMap<'b>, - deps: &'a PackageSet, config: &'b Config<'b>, - host: Layout, target: Option, + pub fn new(env: &'a str, + resolve: &'a Resolve, + sources: &'a SourceMap<'a>, + deps: &'a PackageSet, + config: &'a Config<'b>, + host: Layout, + target_layout: Option, root_pkg: &Package, - build_config: BuildConfig) - -> CargoResult> { - let (target_dylib, target_exe) = - try!(Context::filename_parts(config.target())); - let (host_dylib, host_exe) = if config.target().is_none() { - (target_dylib.clone(), - target_exe.clone()) + build_config: BuildConfig) -> CargoResult> { + let target = build_config.requested_target.clone(); + let target = target.as_ref().map(|s| &s[]); + let (target_dylib, target_exe) = try!(Context::filename_parts(target)); + let (host_dylib, host_exe) = if build_config.requested_target.is_none() { + (target_dylib.clone(), target_exe.clone()) } else { try!(Context::filename_parts(None)) }; - let target_triple = config.target().map(|s| s.to_string()); - let target_triple = target_triple.unwrap_or(config.rustc_host().to_string()); - let cwd = try!(os::getcwd().chain_error(|| { - human("failed to get the current directory") - })); + let target_triple = target.unwrap_or(config.rustc_host()).to_string(); Ok(Context { target_triple: target_triple, env: env, host: host, - target: target, + target: target_layout, resolve: resolve, sources: sources, package_set: deps, @@ -83,7 +80,6 @@ impl<'a, 'b: 'a> Context<'a, 'b> { build_state: Arc::new(BuildState::new(build_config.clone(), deps)), build_config: build_config, exec_engine: Arc::new(Box::new(ProcessEngine) as Box), - cwd: cwd, }) } @@ -151,8 +147,9 @@ impl<'a, 'b: 'a> Context<'a, 'b> { self.build_requirements(pkg, target, Platform::Target); } + let jobs = self.jobs(); self.compilation.extra_env.insert("NUM_JOBS".to_string(), - Some(self.config.jobs().to_string())); + Some(jobs.to_string())); self.compilation.root_output = self.layout(pkg, Kind::Target).proxy().dest().clone(); self.compilation.deps_output = @@ -352,6 +349,14 @@ impl<'a, 'b: 'a> Context<'a, 'b> { Kind::Target => &self.build_config.target, } } + + /// Number of jobs specified for this build + pub fn jobs(&self) -> u32 { self.build_config.jobs } + + /// Requested (not actual) target for the build + pub fn requested_target(&self) -> Option<&str> { + self.build_config.requested_target.as_ref().map(|s| &s[]) + } } impl Platform { diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index 87f8c5c6c..72560226a 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -57,7 +57,7 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform, .env("CARGO_MANIFEST_DIR", Some(pkg.get_manifest_path() .dir_path() .display().to_string())) - .env("NUM_JOBS", Some(cx.config.jobs().to_string())) + .env("NUM_JOBS", Some(cx.jobs().to_string())) .env("TARGET", Some(match kind { Kind::Host => cx.config.rustc_host(), Kind::Target => cx.target_triple(), diff --git a/src/cargo/ops/cargo_rustc/job_queue.rs b/src/cargo/ops/cargo_rustc/job_queue.rs index d6f04e88b..bf6a3dc0d 100644 --- a/src/cargo/ops/cargo_rustc/job_queue.rs +++ b/src/cargo/ops/cargo_rustc/job_queue.rs @@ -63,11 +63,11 @@ pub enum Stage { type Message = (PackageId, Stage, Freshness, CargoResult<()>); impl<'a, 'b> JobQueue<'a, 'b> { - pub fn new(resolve: &'a Resolve, packages: &'a PackageSet, - config: &Config) -> JobQueue<'a, 'b> { + pub fn new(resolve: &'a Resolve, packages: &'a PackageSet, jobs: u32) + -> JobQueue<'a, 'b> { let (tx, rx) = channel(); JobQueue { - pool: TaskPool::new(config.jobs() as usize), + pool: TaskPool::new(jobs as usize), queue: DependencyQueue::new(), tx: tx, rx: rx, diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index c18facd68..95b492634 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -37,6 +37,8 @@ pub enum Kind { Host, Target } pub struct BuildConfig { pub host: TargetConfig, pub target: TargetConfig, + pub jobs: u32, + pub requested_target: Option, } #[derive(Clone, Default)] @@ -113,13 +115,16 @@ fn uniq_target_dest<'a>(targets: &[&'a Target]) -> Option<&'a str> { // Returns a mapping of the root package plus its immediate dependencies to // where the compiled libraries are all located. -pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package, - deps: &PackageSet, resolve: &'a Resolve, - sources: &'a SourceMap, - config: &'a Config<'a>, - build_config: BuildConfig, - exec_engine: Option>>) - -> CargoResult { +pub fn compile_targets<'a, 'b>(env: &str, + targets: &[&'a Target], + pkg: &'a Package, + deps: &PackageSet, + resolve: &'a Resolve, + sources: &'a SourceMap<'a>, + config: &'a Config<'b>, + build_config: BuildConfig, + exec_engine: Option>>) + -> CargoResult { if targets.is_empty() { return Ok(Compilation::new(pkg)) } @@ -136,8 +141,8 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package, deps.iter().find(|p| p.get_package_id() == resolve.root()).unwrap() }; let host_layout = Layout::new(root, None, dest); - let target_layout = config.target().map(|target| { - layout::Layout::new(root, Some(target), dest) + let target_layout = build_config.requested_target.as_ref().map(|target| { + layout::Layout::new(root, Some(&target[]), dest) }); let mut cx = try!(Context::new(env, resolve, sources, deps, config, @@ -147,7 +152,7 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package, cx.exec_engine = exec_engine.clone(); } - let mut queue = JobQueue::new(cx.resolve, deps, cx.config); + let mut queue = JobQueue::new(cx.resolve, deps, cx.jobs()); // First ensure that the destination directory exists try!(cx.prepare(pkg)); @@ -227,7 +232,7 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package, // Prepare the fingerprint directory as the first step of building a package let (target1, target2) = fingerprint::prepare_init(cx, pkg, Kind::Target); let mut init = vec![(Job::new(target1, target2), Fresh)]; - if cx.config.target().is_some() { + if cx.requested_target().is_some() { let (plugin1, plugin2) = fingerprint::prepare_init(cx, pkg, Kind::Host); init.push((Job::new(plugin1, plugin2), Fresh)); } @@ -288,7 +293,7 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package, Platform::Target => reqs.push(Platform::Target), Platform::Plugin => reqs.push(Platform::Plugin), Platform::PluginAndTarget => { - if cx.config.target().is_some() { + if cx.requested_target().is_some() { reqs.push(Platform::Plugin); reqs.push(Platform::Target); } else { @@ -489,7 +494,7 @@ fn rustc(package: &Package, target: &Target, let rustc_dep_info_loc = root.join(target.file_stem()).with_extension("d"); let dep_info_loc = fingerprint::dep_info_loc(cx, package, target, kind); - let cwd = cx.cwd.clone(); + let cwd = cx.config.cwd().clone(); Ok((Work::new(move |desc_tx| { let mut rustc = rustc; @@ -550,7 +555,7 @@ fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>, Ok(match req { Platform::Target => vec![(target_cmd, Kind::Target)], Platform::Plugin => vec![(plugin_cmd, Kind::Host)], - Platform::PluginAndTarget if cx.config.target().is_none() => + Platform::PluginAndTarget if cx.requested_target().is_none() => vec![(target_cmd, Kind::Target)], Platform::PluginAndTarget => vec![(target_cmd, Kind::Target), (plugin_cmd, Kind::Host)], @@ -564,7 +569,7 @@ fn rustdoc(package: &Package, target: &Target, let cx_root = cx.layout(package, kind).proxy().dest().join("doc"); let rustdoc = try!(process(CommandType::Rustdoc, package, target, cx)); let mut rustdoc = rustdoc.arg(root_path(cx, package, target)) - .cwd(cx.cwd.clone()) + .cwd(cx.config.cwd().clone()) .arg("-o").arg(cx_root) .arg("--crate-name").arg(target.get_name()); @@ -626,7 +631,7 @@ fn rustdoc(package: &Package, target: &Target, // absolute paths instead of relative paths. fn root_path(cx: &Context, pkg: &Package, target: &Target) -> Path { let absolute = pkg.get_root().join(target.get_src_path()); - absolute.path_relative_from(&cx.cwd).unwrap_or(absolute) + absolute.path_relative_from(cx.config.cwd()).unwrap_or(absolute) } fn build_base_args(cx: &Context, @@ -637,7 +642,7 @@ fn build_base_args(cx: &Context, let metadata = target.get_metadata(); // Move to cwd so the root_path() passed below is actually correct - cmd = cmd.cwd(cx.cwd.clone()); + cmd = cmd.cwd(cx.config.cwd().clone()); // TODO: Handle errors in converting paths into args cmd = cmd.arg(root_path(cx, pkg, target)); @@ -735,7 +740,7 @@ fn build_plugin_args(mut cmd: CommandPrototype, cx: &Context, pkg: &Package, } } - cmd = opt(cmd, "--target", "", cx.config.target()); + cmd = opt(cmd, "--target", "", cx.requested_target()); cmd = opt(cmd, "-C", "ar=", cx.ar(kind)); cmd = opt(cmd, "-C", "linker=", cx.linker(kind)); } diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 9d18c03b0..28ca81262 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -5,19 +5,21 @@ use sources::PathSource; use ops::{self, ExecEngine, ProcessEngine}; use util::{CargoResult, ProcessError}; -pub struct TestOptions<'a> { - pub compile_opts: ops::CompileOptions<'a>, +pub struct TestOptions<'a, 'b: 'a> { + pub compile_opts: ops::CompileOptions<'a, 'b>, pub no_run: bool, pub name: Option<&'a str>, } pub fn run_tests(manifest_path: &Path, - options: &mut TestOptions, + options: &TestOptions, test_args: &[String]) -> CargoResult> { - let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + let config = options.compile_opts.config; + let mut source = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(source.update()); - let mut compile = try!(ops::compile(manifest_path, &mut options.compile_opts)); + let mut compile = try!(ops::compile(manifest_path, &options.compile_opts)); if options.no_run { return Ok(None) } compile.tests.sort(); @@ -34,10 +36,10 @@ pub fn run_tests(manifest_path: &Path, }; let cmd = try!(compile.target_process(exe, &compile.package)) .args(test_args); - try!(options.compile_opts.shell.concise(|shell| { + try!(config.shell().concise(|shell| { shell.status("Running", to_display.display().to_string()) })); - try!(options.compile_opts.shell.verbose(|shell| { + try!(config.shell().verbose(|shell| { shell.status("Running", cmd.to_string()) })); match ExecEngine::exec(&mut ProcessEngine, cmd) { @@ -58,7 +60,7 @@ pub fn run_tests(manifest_path: &Path, }); for (lib, name) in libs { - try!(options.compile_opts.shell.status("Doc-tests", name)); + try!(config.shell().status("Doc-tests", name)); let mut p = try!(compile.rustdoc_process(&compile.package)) .arg("--test").arg(lib) .arg("--crate-name").arg(name) @@ -80,7 +82,7 @@ pub fn run_tests(manifest_path: &Path, } } - try!(options.compile_opts.shell.verbose(|shell| { + try!(config.shell().verbose(|shell| { shell.status("Running", p.to_string()) })); match ExecEngine::exec(&mut ProcessEngine, p) { @@ -93,7 +95,7 @@ pub fn run_tests(manifest_path: &Path, } pub fn run_benches(manifest_path: &Path, - options: &mut TestOptions, + options: &TestOptions, args: &[String]) -> CargoResult> { let mut args = args.to_vec(); args.push("--bench".to_string()); diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index d023c83c5..28b636f37 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -10,7 +10,7 @@ use registry::{Registry, NewCrate, NewCrateDependency}; use term::color::BLACK; use core::source::Source; -use core::{Package, MultiShell, SourceId}; +use core::{Package, SourceId}; use core::dependency::Kind; use core::manifest::ManifestMetadata; use ops; @@ -26,23 +26,25 @@ pub struct RegistryConfig { } pub fn publish(manifest_path: &Path, - shell: &mut MultiShell, + config: &Config, token: Option, index: Option, verify: bool) -> CargoResult<()> { - let mut src = try!(PathSource::for_path(&manifest_path.dir_path())); + let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(src.update()); let pkg = try!(src.get_root_package()); - let (mut registry, reg_id) = try!(registry(shell, token, index)); + let (mut registry, reg_id) = try!(registry(config, token, index)); try!(verify_dependencies(&pkg, ®_id)); // Prepare a tarball, with a non-surpressable warning if metadata // is missing since this is being put online. - let tarball = try!(ops::package(manifest_path, shell, verify, false, true)).unwrap(); + let tarball = try!(ops::package(manifest_path, config, verify, + false, true)).unwrap(); // Upload said tarball to the specified destination - try!(shell.status("Uploading", pkg.get_package_id().to_string())); + try!(config.shell().status("Uploading", pkg.get_package_id().to_string())); try!(transmit(&pkg, &tarball, &mut registry)); Ok(()) @@ -128,8 +130,8 @@ fn transmit(pkg: &Package, tarball: &Path, registry: &mut Registry) }) } -pub fn registry_configuration() -> CargoResult { - let configs = try!(config::all_configs(try!(os::getcwd()))); +pub fn registry_configuration(config: &Config) -> CargoResult { + let configs = try!(config.values()); let registry = match configs.get("registry") { None => return Ok(RegistryConfig { index: None, token: None }), Some(registry) => try!(registry.table().chain_error(|| { @@ -155,33 +157,32 @@ pub fn registry_configuration() -> CargoResult { Ok(RegistryConfig { index: index, token: token }) } -pub fn registry(shell: &mut MultiShell, +pub fn registry(config: &Config, token: Option, index: Option) -> CargoResult<(Registry, SourceId)> { // Parse all configuration options let RegistryConfig { token: token_config, index: index_config, - } = try!(registry_configuration()); + } = try!(registry_configuration(config)); let token = token.or(token_config); let index = index.or(index_config).unwrap_or(RegistrySource::default_url()); let index = try!(index.as_slice().to_url().map_err(human)); let sid = SourceId::for_registry(&index); let api_host = { - let mut config = try!(Config::new(shell, None, None)); - let mut src = RegistrySource::new(&sid, &mut config); + let mut src = RegistrySource::new(&sid, config); try!(src.update().chain_error(|| { human(format!("Failed to update registry {}", index)) })); (try!(src.config())).api }; - let handle = try!(http_handle()); + let handle = try!(http_handle(config)); Ok((Registry::new_handle(api_host, token, handle), sid)) } /// Create a new HTTP handle with appropriate global configuration for cargo. -pub fn http_handle() -> CargoResult { - Ok(match try!(http_proxy()) { +pub fn http_handle(config: &Config) -> CargoResult { + Ok(match try!(http_proxy(config)) { Some(proxy) => http::handle().proxy(proxy), None => http::handle(), }) @@ -191,8 +192,8 @@ pub fn http_handle() -> CargoResult { /// /// Favor cargo's `http.proxy`, then git's `http.proxy`, then finally a /// HTTP_PROXY env var. -pub fn http_proxy() -> CargoResult> { - let configs = try!(config::all_configs(try!(os::getcwd()))); +pub fn http_proxy(config: &Config) -> CargoResult> { + let configs = try!(config.values()); match configs.get("http") { Some(http) => { let http = try!(http.table().chain_error(|| { @@ -221,9 +222,8 @@ pub fn http_proxy() -> CargoResult> { Ok(os::getenv("HTTP_PROXY")) } -pub fn registry_login(shell: &mut MultiShell, token: String) -> CargoResult<()> { - let config = try!(Config::new(shell, None, None)); - let RegistryConfig { index, token: _ } = try!(registry_configuration()); +pub fn registry_login(config: &Config, token: String) -> CargoResult<()> { + let RegistryConfig { index, token: _ } = try!(registry_configuration(config)); let mut map = HashMap::new(); let p = try!(os::getcwd()); match index { @@ -234,7 +234,7 @@ pub fn registry_login(shell: &mut MultiShell, token: String) -> CargoResult<()> } map.insert("token".to_string(), ConfigValue::String(token, p)); - config::set_config(&config, Location::Global, "registry", + config::set_config(config, Location::Global, "registry", ConfigValue::Table(map)) } @@ -247,26 +247,27 @@ pub struct OwnersOptions { pub list: bool, } -pub fn modify_owners(shell: &mut MultiShell, - opts: &OwnersOptions) -> CargoResult<()> { +pub fn modify_owners(config: &Config, opts: &OwnersOptions) -> CargoResult<()> { let name = match opts.krate { Some(ref name) => name.clone(), None => { let manifest_path = try!(find_root_manifest_for_cwd(None)); - let mut src = try!(PathSource::for_path(&manifest_path.dir_path())); + let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(src.update()); let pkg = try!(src.get_root_package()); pkg.get_name().to_string() } }; - let (mut registry, _) = try!(registry(shell, opts.token.clone(), + let (mut registry, _) = try!(registry(config, opts.token.clone(), opts.index.clone())); match opts.to_add { Some(ref v) => { let v = v.iter().map(|s| s.as_slice()).collect::>(); - try!(shell.status("Owner", format!("adding `{:#?}` to `{}`", v, name))); + try!(config.shell().status("Owner", format!("adding `{:#?}` to `{}`", + v, name))); try!(registry.add_owners(name.as_slice(), v.as_slice()).map_err(|e| { human(format!("failed to add owners: {}", e)) })); @@ -277,8 +278,8 @@ pub fn modify_owners(shell: &mut MultiShell, match opts.to_remove { Some(ref v) => { let v = v.iter().map(|s| s.as_slice()).collect::>(); - try!(shell.status("Owner", format!("removing `{:?}` from `{}`", - v, name))); + try!(config.shell().status("Owner", format!("removing `{:?}` from `{}`", + v, name))); try!(registry.remove_owners(name.as_slice(), v.as_slice()).map_err(|e| { human(format!("failed to add owners: {}", e)) })); @@ -304,7 +305,7 @@ pub fn modify_owners(shell: &mut MultiShell, Ok(()) } -pub fn yank(shell: &mut MultiShell, +pub fn yank(config: &Config, krate: Option, version: Option, token: Option, @@ -314,7 +315,8 @@ pub fn yank(shell: &mut MultiShell, Some(name) => name, None => { let manifest_path = try!(find_root_manifest_for_cwd(None)); - let mut src = try!(PathSource::for_path(&manifest_path.dir_path())); + let mut src = try!(PathSource::for_path(&manifest_path.dir_path(), + config)); try!(src.update()); let pkg = try!(src.get_root_package()); pkg.get_name().to_string() @@ -325,15 +327,15 @@ pub fn yank(shell: &mut MultiShell, None => return Err(human("a version must be specified to yank")) }; - let (mut registry, _) = try!(registry(shell, token, index)); + let (mut registry, _) = try!(registry(config, token, index)); if undo { - try!(shell.status("Unyank", format!("{}:{}", name, version))); + try!(config.shell().status("Unyank", format!("{}:{}", name, version))); try!(registry.unyank(name.as_slice(), version.as_slice()).map_err(|e| { human(format!("failed to undo a yank: {}", e)) })); } else { - try!(shell.status("Yank", format!("{}:{}", name, version))); + try!(config.shell().status("Yank", format!("{}:{}", name, version))); try!(registry.yank(name.as_slice(), version.as_slice()).map_err(|e| { human(format!("failed to yank: {}", e)) })); @@ -342,7 +344,7 @@ pub fn yank(shell: &mut MultiShell, Ok(()) } -pub fn search(query: &str, shell: &mut MultiShell, index: Option) -> CargoResult<()> { +pub fn search(query: &str, config: &Config, index: Option) -> CargoResult<()> { fn truncate_with_ellipsis(s: &str, max_length: usize) -> String { if s.len() < max_length { s.to_string() @@ -351,8 +353,7 @@ pub fn search(query: &str, shell: &mut MultiShell, index: Option) -> Car } } - let (mut registry, _) = try!(registry(shell, None, index)); - + let (mut registry, _) = try!(registry(config, None, index)); let crates = try!(registry.search(query).map_err(|e| { human(format!("failed to retrieve search results from the registry: {}", e)) })); @@ -378,7 +379,7 @@ pub fn search(query: &str, shell: &mut MultiShell, index: Option) -> Car } None => name }; - try!(shell.say(line, BLACK)); + try!(config.shell().say(line, BLACK)); } Ok(()) diff --git a/src/cargo/sources/git/source.rs b/src/cargo/sources/git/source.rs index e649843b9..e6ae188df 100644 --- a/src/cargo/sources/git/source.rs +++ b/src/cargo/sources/git/source.rs @@ -18,7 +18,7 @@ pub struct GitSource<'a, 'b:'a> { db_path: Path, checkout_path: Path, source_id: SourceId, - path_source: Option, + path_source: Option>, rev: Option, config: &'a Config<'b>, } @@ -183,7 +183,8 @@ impl<'a, 'b> Source for GitSource<'a, 'b> { try!(repo.copy_to(actual_rev.clone(), &self.checkout_path)); let source_id = self.source_id.with_precise(Some(actual_rev.to_string())); - let path_source = PathSource::new(&self.checkout_path, &source_id); + let path_source = PathSource::new(&self.checkout_path, &source_id, + self.config); self.path_source = Some(path_source); self.rev = Some(actual_rev); diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index c1278c18e..569188c26 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -6,35 +6,38 @@ use git2; use core::{Package, PackageId, Summary, SourceId, Source, Dependency, Registry}; use ops; -use util::{CargoResult, internal, internal_error, human, ChainError}; +use util::{CargoResult, internal, internal_error, human, ChainError, Config}; -pub struct PathSource { +pub struct PathSource<'a, 'b: 'a> { id: SourceId, path: Path, updated: bool, - packages: Vec + packages: Vec, + config: &'a Config<'b>, } // TODO: Figure out if packages should be discovered in new or self should be // mut and packages are discovered in update -impl PathSource { - - pub fn for_path(path: &Path) -> CargoResult { +impl<'a, 'b> PathSource<'a, 'b> { + pub fn for_path(path: &Path, config: &'a Config<'b>) + -> CargoResult> { log!(5, "PathSource::for_path; path={}", path.display()); - Ok(PathSource::new(path, &try!(SourceId::for_path(path)))) + Ok(PathSource::new(path, &try!(SourceId::for_path(path)), config)) } /// Invoked with an absolute path to a directory that contains a Cargo.toml. /// The source will read the manifest and find any other packages contained /// in the directory structure reachable by the root manifest. - pub fn new(path: &Path, id: &SourceId) -> PathSource { + pub fn new(path: &Path, id: &SourceId, config: &'a Config<'b>) + -> PathSource<'a, 'b> { log!(5, "new; id={}", id); PathSource { id: id.clone(), path: path.clone(), updated: false, - packages: Vec::new() + packages: Vec::new(), + config: config, } } @@ -55,7 +58,7 @@ impl PathSource { if self.updated { Ok(self.packages.clone()) } else { - ops::read_packages(&self.path, &self.id) + ops::read_packages(&self.path, &self.id, self.config) } } @@ -198,13 +201,13 @@ impl PathSource { } } -impl Show for PathSource { +impl<'a, 'b> Show for PathSource<'a, 'b> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "the paths source") } } -impl Registry for PathSource { +impl<'a, 'b> Registry for PathSource<'a, 'b> { fn query(&mut self, dep: &Dependency) -> CargoResult> { let mut summaries: Vec = self.packages.iter() .map(|p| p.get_summary().clone()) @@ -213,7 +216,7 @@ impl Registry for PathSource { } } -impl Source for PathSource { +impl<'a, 'b> Source for PathSource<'a, 'b> { fn update(&mut self) -> CargoResult<()> { if !self.updated { let packages = try!(self.read_packages()); diff --git a/src/cargo/sources/registry.rs b/src/cargo/sources/registry.rs index 0c40ee4cc..392d5e78f 100644 --- a/src/cargo/sources/registry.rs +++ b/src/cargo/sources/registry.rs @@ -186,7 +186,7 @@ pub struct RegistrySource<'a, 'b:'a> { src_path: Path, config: &'a Config<'b>, handle: Option, - sources: Vec, + sources: Vec>, hashes: HashMap<(String, String), String>, // (name, vers) => cksum cache: HashMap>, updated: bool, @@ -249,8 +249,8 @@ impl<'a, 'b> RegistrySource<'a, 'b> { /// /// This is the main cargo registry by default, but it can be overridden in /// a .cargo/config - pub fn url() -> CargoResult { - let config = try!(ops::registry_configuration()); + pub fn url(config: &Config) -> CargoResult { + let config = try!(ops::registry_configuration(config)); let url = config.index.unwrap_or(DEFAULT.to_string()); url.as_slice().to_url().map_err(human) } @@ -306,7 +306,7 @@ impl<'a, 'b> RegistrySource<'a, 'b> { let handle = match self.handle { Some(ref mut handle) => handle, None => { - self.handle = Some(try!(ops::http_handle())); + self.handle = Some(try!(ops::http_handle(self.config))); self.handle.as_mut().unwrap() } }; @@ -511,7 +511,7 @@ impl<'a, 'b> Source for RegistrySource<'a, 'b> { let path = try!(self.unpack_package(package, path).chain_error(|| { internal(format!("Failed to unpack package `{}`", package)) })); - let mut src = PathSource::new(&path, &self.source_id); + let mut src = PathSource::new(&path, &self.source_id, self.config); try!(src.update()); self.sources.push(src); } diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index e80cc23cc..544eff51f 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -1,10 +1,9 @@ use std::{fmt, os, mem}; -use std::cell::{RefCell, RefMut}; +use std::cell::{RefCell, RefMut, Ref, Cell}; use std::collections::hash_map::{HashMap}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::io; use std::io::fs::{self, PathExtensions, File}; -use std::string; use rustc_serialize::{Encodable,Encoder}; use toml; @@ -19,21 +18,19 @@ use self::ConfigValue as CV; pub struct Config<'a> { home_path: Path, shell: RefCell<&'a mut MultiShell>, - jobs: u32, - target: Option, - rustc_version: string::String, + rustc_version: String, /// The current host and default target of rustc - rustc_host: string::String, + rustc_host: String, + values: RefCell>, + values_loaded: Cell, + cwd: Path, } impl<'a> Config<'a> { - pub fn new(shell: &'a mut MultiShell, - jobs: Option, - target: Option) -> CargoResult> { - if jobs == Some(0) { - return Err(human("jobs must be at least 1")) - } - + pub fn new(shell: &'a mut MultiShell) -> CargoResult> { + let cwd = try!(os::getcwd().chain_error(|| { + human("couldn't get the current directory of the process") + })); let (rustc_version, rustc_host) = try!(ops::rustc_version()); Ok(Config { @@ -42,10 +39,11 @@ impl<'a> Config<'a> { This probably means that $HOME was not set.") })), shell: RefCell::new(shell), - jobs: jobs.unwrap_or(os::num_cpus() as u32), - target: target, rustc_version: rustc_version, rustc_host: rustc_host, + cwd: cwd, + values: RefCell::new(HashMap::new()), + values_loaded: Cell::new(false), }) } @@ -75,14 +73,6 @@ impl<'a> Config<'a> { self.shell.borrow_mut() } - pub fn jobs(&self) -> u32 { - self.jobs - } - - pub fn target(&self) -> Option<&str> { - self.target.as_ref().map(|t| t.as_slice()) - } - /// Return the output of `rustc -v verbose` pub fn rustc_version(&self) -> &str { self.rustc_version.as_slice() @@ -92,6 +82,21 @@ impl<'a> Config<'a> { pub fn rustc_host(&self) -> &str { self.rustc_host.as_slice() } + + pub fn values(&self) -> CargoResult>> { + if !self.values_loaded.get() { + try!(self.load_values()); + self.values_loaded.set(true); + } + Ok(self.values.borrow()) + } + + pub fn cwd(&self) -> &Path { &self.cwd } + + fn load_values(&self) -> CargoResult<()> { + *self.values.borrow_mut() = try!(all_configs(&self.cwd)); + Ok(()) + } } #[derive(Eq, PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)] @@ -102,9 +107,9 @@ pub enum Location { #[derive(Eq,PartialEq,Clone,RustcDecodable)] pub enum ConfigValue { - String(string::String, Path), - List(Vec<(string::String, Path)>), - Table(HashMap), + String(String, Path), + List(Vec<(String, Path)>), + Table(HashMap), Boolean(bool, Path), } @@ -135,7 +140,7 @@ impl Encodable for ConfigValue { match *self { CV::String(ref string, _) => string.encode(s), CV::List(ref list) => { - let list: Vec<&string::String> = list.iter().map(|s| &s.0).collect(); + let list: Vec<&String> = list.iter().map(|s| &s.0).collect(); list.encode(s) } CV::Table(ref table) => table.encode(s), @@ -201,7 +206,7 @@ impl ConfigValue { } } - pub fn table(&self) -> CargoResult<&HashMap> { + pub fn table(&self) -> CargoResult<&HashMap> { match *self { CV::Table(ref table) => Ok(table), _ => Err(internal(format!("expected a table, but found a {}", @@ -209,7 +214,7 @@ impl ConfigValue { } } - pub fn list(&self) -> CargoResult<&[(string::String, Path)]> { + pub fn list(&self) -> CargoResult<&[(String, Path)]> { match *self { CV::List(ref list) => Ok(list.as_slice()), _ => Err(internal(format!("expected a list, but found a {}", @@ -260,10 +265,10 @@ pub fn get_config(pwd: Path, key: &str) -> CargoResult { human(format!("`{}` not found in your configuration", key))) } -pub fn all_configs(pwd: Path) -> CargoResult> { +pub fn all_configs(pwd: &Path) -> CargoResult> { let mut cfg = CV::Table(HashMap::new()); - try!(walk_tree(&pwd, |mut file| { + try!(walk_tree(pwd, |mut file| { let path = file.path().clone(); let contents = try!(file.read_to_string()); let table = try!(cargo_toml::parse(contents.as_slice(), &path).chain_error(|| { diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 447ee174e..b7321d46e 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -15,7 +15,7 @@ use core::{Summary, Manifest, Target, Dependency, PackageId, GitReference}; use core::dependency::Kind; use core::manifest::{LibKind, Profile, ManifestMetadata}; use core::package_id::Metadata; -use util::{CargoResult, human, ToUrl, ToSemver, ChainError}; +use util::{CargoResult, human, ToUrl, ToSemver, ChainError, Config}; /// Representation of the projects file layout. /// @@ -91,7 +91,8 @@ pub fn project_layout(root_path: &Path) -> Layout { pub fn to_manifest(contents: &[u8], source_id: &SourceId, - layout: Layout) + layout: Layout, + config: &Config) -> CargoResult<(Manifest, Vec)> { let manifest = layout.root.join("Cargo.toml"); let manifest = match manifest.path_relative_from(&try!(os::getcwd())) { @@ -110,7 +111,7 @@ pub fn to_manifest(contents: &[u8], manifest.display(), e))) }; - let pair = try!(toml_manifest.to_manifest(source_id, &layout).map_err(|err| { + let pair = try!(toml_manifest.to_manifest(source_id, &layout, config).map_err(|err| { human(format!("{} is not a valid manifest\n\n{}", manifest.display(), err)) })); @@ -302,10 +303,11 @@ impl TomlProject { } } -struct Context<'a> { +struct Context<'a, 'b, 'c: 'b> { deps: &'a mut Vec, source_id: &'a SourceId, - nested_paths: &'a mut Vec + nested_paths: &'a mut Vec, + config: &'b Config<'c>, } // These functions produce the equivalent of specific manifest entries. One @@ -380,7 +382,8 @@ fn inferred_bench_targets(layout: &Layout) -> Vec { } impl TomlManifest { - pub fn to_manifest(&self, source_id: &SourceId, layout: &Layout) + pub fn to_manifest(&self, source_id: &SourceId, layout: &Layout, + config: &Config) -> CargoResult<(Manifest, Vec)> { let mut nested_paths = vec!(); @@ -486,7 +489,8 @@ impl TomlManifest { let mut cx = Context { deps: &mut deps, source_id: source_id, - nested_paths: &mut nested_paths + nested_paths: &mut nested_paths, + config: config, }; // Collect the deps @@ -593,7 +597,7 @@ fn process_dependencies(cx: &mut Context, cx.source_id.clone() }) } - }.unwrap_or(try!(SourceId::for_central())); + }.unwrap_or(try!(SourceId::for_central(cx.config))); let dep = try!(Dependency::parse(n.as_slice(), details.version.as_ref() diff --git a/tests/test_cargo.rs b/tests/test_cargo.rs index b24dc6077..618ad281d 100644 --- a/tests/test_cargo.rs +++ b/tests/test_cargo.rs @@ -1,4 +1,4 @@ -use std::io::fs::{self, PathExtensions}; +use std::io::fs; use std::io; use std::io::{USER_RWX, File}; use std::os; @@ -23,14 +23,9 @@ fn fake_executable(proj: ProjectBuilder, dir: &Path, name: &str) -> ProjectBuild proj } -// We can't entirely obliterate PATH because windows needs it for paths to -// things like libgcc, but we want to filter out everything which has a `cargo` -// installation as we don't want it to muck with the --list tests -fn new_path() -> Vec { +fn path() -> Vec { let path = os::getenv_as_bytes("PATH").unwrap_or(Vec::new()); - os::split_paths(path).into_iter().filter(|p| { - !p.join(format!("cargo{}", os::consts::EXE_SUFFIX)).exists() - }).collect() + os::split_paths(path) } test!(list_commands_looks_at_path { let proj = project("list-non-overlapping"); @@ -40,7 +35,7 @@ test!(list_commands_looks_at_path { .cwd(proj.root()) .env("HOME", Some(paths::home())); - let mut path = new_path(); + let mut path = path(); path.push(proj.root().join("path-test")); let path = os::join_paths(path.as_slice()).unwrap(); let output = pr.arg("-v").arg("--list").env("PATH", Some(path.as_slice())); diff --git a/tests/test_cargo_compile_git_deps.rs b/tests/test_cargo_compile_git_deps.rs index b6ab7cdb9..018f45b39 100644 --- a/tests/test_cargo_compile_git_deps.rs +++ b/tests/test_cargo_compile_git_deps.rs @@ -703,19 +703,22 @@ test!(update_with_shared_deps { // By default, not transitive updates println!("dep1 update"); - assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1"), + assert_that(p.process(cargo_dir().join("cargo")).arg("update") + .arg("-p").arg("dep1"), execs().with_stdout("")); // Specifying a precise rev to the old rev shouldn't actually update // anything because we already have the rev in the db. println!("bar precise update"); - assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("bar") + assert_that(p.process(cargo_dir().join("cargo")).arg("update") + .arg("-p").arg("bar") .arg("--precise").arg(old_head.to_string()), execs().with_stdout("")); // Updating aggressively should, however, update the repo. println!("dep1 aggressive update"); - assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1") + assert_that(p.process(cargo_dir().join("cargo")).arg("update") + .arg("-p").arg("dep1") .arg("--aggressive"), execs().with_stdout(format!("{} git repository `{}`", UPDATING, @@ -733,7 +736,8 @@ test!(update_with_shared_deps { compiling = COMPILING, dir = p.url()))); // We should be able to update transitive deps - assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("bar"), + assert_that(p.process(cargo_dir().join("cargo")).arg("update") + .arg("-p").arg("bar"), execs().with_stdout(format!("{} git repository `{}`", UPDATING, git_project.url()))); -- 2.30.2